using System;
using System.Collections.Generic;
using System.Text;
using Index.TemporaryFile;
using System.IO;
using Coding;

namespace Index.TemporaryFile
{
    public class TermEntryFile
    {
        private String path;
        private FileStream stream;
       

        public TermEntryFile(String path)
        {
            this.path = path;
        }

        public void Open()
        {
            this.stream = new FileStream(path, FileMode.OpenOrCreate);
        }



        public long TermEntryCount
        {
            get
            {
                long length =  stream.Length / 12;
                return length;
            }
        }

        public TermEntry this[long position]
        {
            get
            {
               
                long dest = 12 * position;
                stream.Seek(dest - stream.Position, SeekOrigin.Current);
              

                byte[] entry = new byte[12];
                stream.Read(entry, 0, 12);

                /*int doc_id = BitConverter.ToInt32(entry, 0);
                int term_id = BitConverter.ToInt32(entry, 4);
                int freq = BitConverter.ToInt32(entry, 8);*/

                int doc_id = IntConverter.FromBytes(entry, 0);
                int term_id = IntConverter.FromBytes(entry, 4);
                int freq = IntConverter.FromBytes(entry, 8);


                return new TermEntry(term_id, doc_id, freq);

            }
            set
            {
                
                long dest = 12 * position;
                stream.Seek(dest - stream.Position, SeekOrigin.Current);
 
                
                /*byte[] doc_id = BitConverter.GetBytes(value.DocumentID);
                byte[] term_id = BitConverter.GetBytes(value.TermID);
                byte[] freq = BitConverter.GetBytes(value.FreqORPosition);*/
                

                byte[] doc_id = IntConverter.ToBytes(value.DocumentID);
                byte[] term_id = IntConverter.ToBytes(value.TermID);
                byte[] freq = IntConverter.ToBytes(value.Position);



                stream.Write(doc_id, 0, doc_id.Length);
                stream.Write(term_id, 0, term_id.Length);
                stream.Write(freq, 0, freq.Length);
            }
        }

        public void Append(TermEntry entry)
        {
            /*byte[] doc_id = BitConverter.GetBytes(entry.DocumentID);
            byte[] term_id = BitConverter.GetBytes(entry.TermID);
            byte[] freq = BitConverter.GetBytes(entry.FreqORPosition);*/

            //Console.WriteLine("Append {0} {1} {2}", entry.TermID, entry.DocumentID, entry.Position);
            
            byte[] doc_id = IntConverter.ToBytes(entry.DocumentID);
            byte[] term_id = IntConverter.ToBytes(entry.TermID);
            byte[] freq = IntConverter.ToBytes(entry.Position);

            stream.Seek(0, SeekOrigin.End);

            stream.Write(doc_id, 0, doc_id.Length);
            stream.Write(term_id, 0, term_id.Length);
            stream.Write(freq, 0, freq.Length);
        }


        public void Append(TermEntry[] entries)
        {
            foreach (TermEntry entry in entries)
            {
                Append(entry);
            }
        }

        public void Flush()
        {
            stream.Flush();
        }

        public void Close()
        {
            stream.Flush();
            stream.Close();
        }

     
        public TermEntry[] Read(long offset, long count)
        {
            TermEntry[] result = new TermEntry[count];


            for (int i = 0; i < count; i++)
            {
                result[i] = this[i + offset];
            }
            return result;

        }

        public void Write(long offset, TermEntry[] block)
        {
            for (int i = 0; i < block.Length; i++)
            {
                this[i + offset] = block[i];
            }
        }
    }
}
